/**
*
* @author zzhijie
* @date 2020-08-19
*/

<template>
  <div
    ref="dragItem"
    class="drag-item"
    :class="[moveFlag?'moving':'']"
    :style="getStyle"
    @mousedown.stop="handleMoveStart">
    <slot></slot>
    <template v-if="resizeFlag">
      <span class="scale-se" @mousedown.stop="handleScaleStart(0,$event)"></span>
      <span class="scale-s" @mousedown.stop="handleScaleStart(1,$event)"></span>
      <span class="scale-e" @mousedown.stop="handleScaleStart(2,$event)"></span>
    </template>
  </div>
</template>

<script>

export default {
  name: "anyDragItem",
  props: {
    size: {
      type: Object,
    },
    ratio: {
      type: Number,
      default: 1
    },
    dragAreaId: {
      type: String
    },
    resizeFlag: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      isDragItem: true,
      moveFlag: false,
      scaleFlag: false,
      width: 0,
      height: 0,
      top: 0,
      left: 0,
      rect: {},
    }
  },
  computed: {
    getStyle() {
      let {top, left, width, height} = this.size || {};
      return {
        top: top + 'px',
        left: left + 'px',
        width: width + 'px',
        height: height + 'px',
      }
    },
    dragArea() {
      return document.getElementById(this.dragAreaId);
    }
  },
  watch: {},
  methods: {
    handleMoveStart(e) {
      addEventListener("mousemove", this.handleMove);
      addEventListener("mouseup", this.handleMoveEnd);
      this.rect = this.$refs.dragItem.getBoundingClientRect();
      this.x = e.pageX - this.rect.left;
      this.y = e.pageY - this.rect.top;
      this.moveFlag = true;
    },
    handleMove(e) {
      if (!this.moveFlag) return;
      let {top, left, width, height} = this.dragArea.getBoundingClientRect();
      let diff = 15;
      let {pageX, pageY} = e;
      let size = this.size;
      let curTop = (pageY - this.y - top) / this.ratio;
      let curLeft = (pageX - this.x - left) / this.ratio;
      let right = (width - this.rect.width) / this.ratio;
      let bottom = (height - this.rect.height) / this.ratio;
      if (curTop <= diff && curTop >= -diff) {
        size.top = 0;
      } else if (curTop <= bottom + diff && curTop >= bottom - diff) {
        size.top = bottom;
      } else {
        size.top = curTop;
      }
      if (curLeft <= diff && curLeft >= -diff) {
        size.left = 0;
      } else if (curLeft <= right + diff && curLeft >= right - diff) {
        size.left = right;
      } else {
        size.left = curLeft;
      }
    },
    handleMoveEnd() {
      removeEventListener("mousemove", this.handleMove);
      removeEventListener("mouseup", this.handleMoveEnd);
      this.moveFlag = false;
    },
    handleScaleStart(type, e) {
      e.stopPropagation();
      this.type = type;
      this.scaleFlag = true;
      this.x = e.pageX;
      this.y = e.pageY;
      this.width = this.size.width;
      this.height = this.size.height;
      addEventListener("mousemove", this.handleScale);
      addEventListener("mouseup", this.handleScaleEnd);
    },
    handleScale(e) {
      if (!this.scaleFlag) return;
      let {pageX, pageY} = e;
      if (this.type === 0 || this.type === 2) {
        this.size.width = this.width + (pageX - this.x) / this.ratio;
      }
      if (this.type === 0 || this.type === 1) {
        this.size.height = this.height + (pageY - this.y) / this.ratio;
      }
    },
    handleScaleEnd() {
      removeEventListener("mousemove", this.handleScale);
      removeEventListener("mouseup", this.handleScaleEnd);
      this.scaleFlag = false;
    },
    mounted() {
    },
    beforeDestroy() {
      this.handleMoveEnd();
      this.handleScaleEnd();
    }
  }
}
</script>

<style lang="scss" scoped>

.drag-item {
  position: absolute;
  cursor: move;
  transition: opacity .15s;

  &.moving {
    opacity: .6;
  }

  .scale-se {
    position: absolute;
    bottom: -10px;
    right: -10px;
    width: 20px;
    height: 20px;
    z-index: 101;
    cursor: se-resize;
  }

  .scale-s {
    position: absolute;
    bottom: -2px;
    left: 0;
    width: 100%;
    height: 4px;
    z-index: 100;
    cursor: s-resize;
  }

  .scale-e {
    position: absolute;
    right: -2px;
    bottom: 0;
    width: 4px;
    height: calc(100% - 30px);
    z-index: 100;
    cursor: e-resize;
  }
}

</style>
